import cv2
from PIL import Image
import numpy as np

# 自定义顺序矩阵，根据题目中提供的顺序图
custom_order = [
    255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240,
    224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
    223, 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 208,
    192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
    191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 176,
    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
    159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144,
    128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
    127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112,
    96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
    95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,
    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
    63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48,
    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
    31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
]


# 读取图像帧并调整为16x16
def resize_image_frame(frame):
    img = Image.fromarray(frame)
    img = img.resize((16, 16))  # 调整为16x16像素
    img = img.convert('RGB')  # 确保图像是RGB模式
    return np.array(img)  # 返回NumPy数组格式，方便后续处理


# 处理视频并逐帧保存矩阵，同时进行预览和保存转换后的视频
def process_video(video_path, output_file, output_video_path):
    # 打开视频文件
    cap = cv2.VideoCapture(video_path)

    # 获取视频的宽度、高度和帧率
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps = 30

    # 打开视频写入器，保存16x16大小的视频
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter(output_video_path, fourcc, fps, (160, 160))  # 保存为160x160以便预览

    frame_number = 0  # 帧计数器

    # 清空输出文件
    with open(output_file, 'w') as f:
        f.write("// Video frames stored as 16x16 matrices\n\n")

    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break  # 视频读取完毕

        # 将帧调整为16x16
        img = resize_image_frame(frame)

        # 将16x16的图像放大到160x160，以便查看
        img_enlarged = cv2.resize(img, (160, 160), interpolation=cv2.INTER_NEAREST)

        # 显示转换后的帧
        cv2.imshow('16x16 Video Preview', img_enlarged)

        # 保存帧到输出视频文件
        out.write(img_enlarged)

        # 获取颜色编码
        color_codes = get_color_codes(img)

        # 保存当前帧的矩阵到文件
        save_frame_to_file(color_codes, frame_number, output_file)

        frame_number += 1

        # 按下 'q' 键退出预览
        if cv2.waitKey(int(1000 / fps)) & 0xFF == ord('q'):
            break

    cap.release()
    out.release()
    cv2.destroyAllWindows()


# 获取图像的颜色编码
def get_color_codes(img):
    pixels = img.reshape((16 * 16, 3))  # 获取所有像素并展开为一维
    color_codes = []

    for i in custom_order:
        r, g, b = pixels[i]  # 获取RGB值
        # 转换为16进制颜色代码
        hex_color = f"0x{r:02X}{g:02X}{b:02X}"
        color_codes.append(hex_color)

    return color_codes


# 保存每一帧的矩阵到文件
def save_frame_to_file(color_codes, frame_number, output_file):
    with open(output_file, 'a') as f:  # 以追加模式打开文件
        f.write(f"const int Frame{frame_number}[] PROGMEM = {{\n")
        for i in range(0, len(color_codes), 16):
            line = ",".join(color_codes[i:i + 16])
            f.write(f"  {line},\n")
        f.write("};\n\n")


# 主程序
video_path = '2.mp4'  # 替换为你的视频文件路径
output_file = 'frames_output_2.txt'  # 保存矩阵结果的文件
output_video_path = 'output_video.avi'  # 保存转换后的视频文件

# 处理视频，预览并保存转换后的16x16视频
process_video(video_path, output_file, output_video_path)

print(f"视频已处理完毕，帧矩阵已保存到 {output_file}，转换后的视频已保存到 {output_video_path}")